package chances.system.operator.web;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import chances.commons.crypto.MD5Util;
import chances.system.json.JsonResponse;
import chances.system.log.entity.ActionLog;
import chances.system.operator.entity.Operator;
import chances.system.operator.entity.OperatorRole;
import chances.system.operator.entity.Oplog;
import chances.system.operator.repo.OperatorRepository;
import chances.system.operator.repo.OperatorRoleRepository;


@RestController
public class OperatorController{

	ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
	 
	@Autowired
	OperatorRepository operatorRepository;
	
	@Autowired
	OperatorRoleRepository operatorRoleRepository;
	
    private static Md5PasswordEncoder passEncoder = new Md5PasswordEncoder();  
    
	@ActionLog(operateType=Oplog.OP_EDIT, objName="operator", desc="修改操作员'{name}'")
    @RequestMapping(path = "/sys/operator/save", method = RequestMethod.POST)
	public Operator saveOperator(HttpServletRequest request, @RequestBody OperatorModel model) {
		List<Long> roleIds = model.getRoles();
		roleIds.remove(null);		
		
		Operator operator = null;
		if (model.getId() == null){
			operator = model.getOperator();
			setOperatotPwd(operator);
		}else{
			operator = operatorRepository.findOne(model.getId());
			Operator operatorNew = model.getOperator();
			operator.setName(operatorNew.getName());
			operator.setEmail(operatorNew.getEmail());
			operator.setMobile(operatorNew.getMobile());
			operator.setOrgId(operatorNew.getOrgId());
		}
		this.operatorRepository.save(operator);
		
		List<OperatorRole> operatorRoles = new ArrayList<OperatorRole>();
		if (model.getId() == null) {
			if (!roleIds.isEmpty()) {
				for (Long roleId : roleIds) {
					OperatorRole operatorRole = new OperatorRole();
					operatorRole.setId(model.getId());
					operatorRole.setRoleId(roleId);
					operatorRoles.add(operatorRole);
				}
			}
		} else {
			List<OperatorRole> operatorRolesOld 
				= operatorRoleRepository.findById(model.getId());
			
			for (OperatorRole operatorRoleOld : operatorRolesOld) {
				if(model.getRoles().contains(operatorRoleOld.getRoleId())){
					roleIds.remove(operatorRoleOld.getRoleId());
				}else{
					operatorRoleRepository.delete(operatorRoleOld);
				}
			}

			if (!roleIds.isEmpty()) {
				for (Long roleId : roleIds) {
					OperatorRole operatorRole = new OperatorRole();
					operatorRole.setId(model.getId());
					operatorRole.setRoleId(roleId);
					operatorRoles.add(operatorRole);
				}
			}
		}
		if(!operatorRoles.isEmpty()){
			operatorRoleRepository.save(operatorRoles);
		}
		request.setAttribute("operator", operator);
		return operator;
	}

	@ActionLog(operateType=Oplog.OP_EDIT, objName="operator", desc="修改操作员'{name}'状态")
	@RequestMapping(path = "/sys/operator/status", method = RequestMethod.POST)
	public Operator updateStatus(HttpServletRequest request, @RequestBody OperatorModel model) {
		Operator operator = this.operatorRepository.findOne(model.getId());
		operator.setStatus(model.getStatus());
		operator = this.operatorRepository.save(operator);
		request.setAttribute("operator", operator);
		return operator;
	}
	
	@RequestMapping(path = "/sys/operator/password/{id}/{password}", method = RequestMethod.GET)
	public JsonResponse updatePassword(HttpServletRequest request
			, @PathVariable("id") Long id, @PathVariable("password") String password, Model model) {
		Operator operator = operatorRepository.findOne(id);
		JsonResponse response = new JsonResponse();
		if(operator.getPassword().equals(getEncodingPwd(password, operator.getSalt()))){
			response.setResult(JsonResponse.RESULT_FAILED);
		}
		return response;
	}

	@ActionLog(operateType=Oplog.OP_EDIT, objName="operator", desc="修改操作员'{name}'密码")
	@RequestMapping(path = "/sys/operator/password", method = RequestMethod.POST)
	public Operator updatePassword(HttpServletRequest request, @RequestBody OperatorModel model) {
		Operator operator = operatorRepository.findOne(model.getId());
		operator.setPassword(model.getPassword());
		setOperatotPwd(operator);
		operator = this.operatorRepository.save(operator);
		request.setAttribute("operator", operator);
		return operator;
	}
	
    private void setOperatotPwd(Operator operator) {
        String password = operator.getPassword();
        operator.setSalt(MD5Util.MD5(UUID.randomUUID().toString()));
        operator.setPassword(getEncodingPwd(password,operator.getSalt()));
    }
	
	private String getEncodingPwd(String plainTextPwd,String salt){ 
		String newPwd = passEncoder.encodePassword(plainTextPwd, salt);
		return newPwd;
	}
}
